/*
 * Package il.ac.biu.cs.grossmm.test.FooProtocol
 * File Capabilities.java
 * 
 * This is a part of presence service framework API. 
 * See javadoc for more information.
 *  
 * Copyright (C) 2006 Grossmann Mark
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package il.ac.biu.cs.grossmm.foo.format;

import java.util.AbstractSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public abstract class Capabilities extends AbstractSet<String> {
	public static Capabilities of(String c)
	{
		return new Simple(c);
	}

	public static Capabilities of(String... cs)
	{
		if (cs.length == 1)
			return new Simple(cs[0]);

		return new Complex(cs.clone());
	}
	
	public static Capabilities of(Set<String> set) {
		if( set.size() == 1 )
			return new Simple(set.iterator().next());
		
		return new Complex(set);
	}

	public static Capabilities union(Capabilities a, Capabilities b)
	{
		if (a.size() < b.size())
			return union(b, a);

		if (a instanceof Simple)
			if (b.size() == 0 || ((Simple) b).capability.equals(a))
				return a;
			else
				return new Complex(new String[] { ((Simple) a).capability,
					((Simple) b).capability });

		HashSet<String> hs = new HashSet<String>();
		
		for( String s : a )
			hs.add(s);
		
		for( String s : b )
			hs.add(s);
		
		return new Complex(hs);
		
	}

	static class Complex extends Capabilities {
		final String[] caps;

		public Complex(final String[] caps)
		{
			this.caps = caps;
		}
		
		public Complex(Set<String> set) {
			caps = new String[set.size()];
			
			set.toArray(caps);
		}

		@Override
		public Iterator<String> iterator()
		{
			return new Iterator<String>() {
				int index = 0;

				public boolean hasNext()
				{
					return index < caps.length;
				}

				public String next()
				{
					return caps[index++];
				}

				public void remove()
				{
					throw new UnsupportedOperationException();
				}
			};
		}

		@Override
		public int size()
		{
			return caps.length;
		}

	}

	static class Simple extends Capabilities {
		final String capability;

		public Simple(final String capability)
		{
			super();
			this.capability = capability;
		}

		@Override
		public Iterator<String> iterator()
		{
			return new Iterator<String>() {
				boolean hasNext = true;

				public boolean hasNext()
				{
					boolean r = hasNext;
					hasNext = false;
					return r;
				}

				public String next()
				{
					return capability;
				}

				public void remove()
				{
					throw new UnsupportedOperationException();
				}

			};
		}

		@Override
		public int size()
		{
			return 1;
		}
	}
}
